---
title: "Animation"
description: "Utilities for animating elements with CSS animations."
---

import redent from 'redent'
import { Variants } from '@/components/Variants'
import { Disabling } from '@/components/Disabling'

export const classes = (
  <div className="overflow-y-auto scrollbar-w-2 scrollbar-track-gray-lighter scrollbar-thumb-rounded scrollbar-thumb-gray scrolling-touch lg:max-h-sm">
    <table className="w-full text-left border-collapse">
      <thead>
        <tr>
          <th className="z-20 sticky top-0 text-sm font-semibold text-gray-600 bg-white p-0">
            <div className="pb-2 border-b border-gray-200">Class</div>
          </th>
          <th className="z-20 sticky top-0 text-sm font-semibold text-gray-600 bg-white p-0">
            <div className="pb-2 border-b border-gray-200">Properties</div>
          </th>
        </tr>
      </thead>
      <tbody className="align-baseline">
        <tr>
          <td translate="no" className="py-2 font-mono text-xs text-violet-600 whitespace-nowrap">
            animate-none
          </td>
          <td translate="no" className="py-2 font-mono text-xs text-light-blue-600 whitespace-pre">
            animation: none;
          </td>
        </tr>
        <tr>
          <td translate="no" className="py-2 font-mono text-xs text-violet-600 whitespace-nowrap border-t border-gray-200">
            animate-spin
          </td>
          <td translate="no" className="py-2 font-mono text-xs text-light-blue-600 whitespace-pre border-t border-gray-200">
            {redent(`
              animation: spin 1s linear infinite;\n
              @keyframes spin {
                from {
                  transform: rotate(0deg);
                }
                to {
                  transform: rotate(360deg);
                }
              }
            `).trim()}
          </td>
        </tr>
        <tr>
          <td translate="no" className="py-2 font-mono text-xs text-violet-600 whitespace-nowrap border-t border-gray-200">
            animate-ping
          </td>
          <td translate="no" className="py-2 font-mono text-xs text-light-blue-600 whitespace-pre border-t border-gray-200">
            {redent(`
              animation: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;\n
              @keyframes ping {
                75%, 100% {
                  transform: scale(2);
                  opacity: 0;
                }
              }
            `).trim()}
          </td>
        </tr>
        <tr>
          <td translate="no" className="py-2 font-mono text-xs text-violet-600 whitespace-nowrap border-t border-gray-200">
            animate-pulse
          </td>
          <td translate="no" className="py-2 font-mono text-xs text-light-blue-600 whitespace-pre border-t border-gray-200">
            {redent(`
              animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n
              @keyframes pulse {
                0%, 100% {
                  opacity: 1;
                }
                50% {
                  opacity: .5;
                }
              }
            `).trim()}
          </td>
        </tr>
        <tr>
          <td translate="no" className="py-2 font-mono text-xs text-violet-600 whitespace-nowrap border-t border-gray-200">
            animate-bounce
          </td>
          <td translate="no" className="py-2 font-mono text-xs text-light-blue-600 whitespace-pre border-t border-gray-200">
            {redent(`
              animation: bounce 1s infinite;\n
              @keyframes bounce {
                0%, 100% {
                  transform: translateY(-25%);
                  animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
                }
                50% {
                  transform: translateY(0);
                  animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
                }
              }
            `).trim()}
          </td>
        </tr>
      </tbody>
    </table>
  </div>
)

## Spin

Add the `animate-spin` utility to add a linear spin animation to elements like loading indicators.

```html rose
<template preview>
  <div class="flex justify-around">
    <span class="inline-flex rounded-md shadow-sm">
      <button type="button" class="inline-flex items-center px-4 py-2 border border-transparent text-base leading-6 font-medium rounded-md text-white bg-rose-600 hover:bg-rose-500 focus:border-rose-700 active:bg-rose-700 transition ease-in-out duration-150 cursor-not-allowed" disabled>
        <svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
          <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
          <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
        </svg>
        Processing
      </button>
    </span>
  </div>
</template>

<button type="button" class="bg-rose-600 ..." disabled>
  <svg class="**animate-spin** h-5 w-5 mr-3 ..." viewBox="0 0 24 24">
    <!-- ... -->
  </svg>
  Processing
</button>
```

## Ping

Add the `animate-ping` utility to make an element scale and fade like a radar ping or ripple of water — useful for things like notification badges.

```html purple
<template preview>
  <div class="flex justify-around">
    <span class="relative inline-flex rounded-md shadow-sm">
      <button type="button" class="inline-flex items-center px-4 py-2 border border-purple-400 text-base leading-6 font-medium rounded-md text-purple-800 bg-white hover:text-purple-700 focus:border-purple-300 transition ease-in-out duration-150">
        Transactions
      </button>
      <span class="flex absolute h-3 w-3 top-0 right-0 -mt-1 -mr-1">
        <span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-purple-400 opacity-75"></span>
        <span class="relative inline-flex rounded-full h-3 w-3 bg-purple-500"></span>
      </span>
    </span>
  </div>
</template>

<span class="flex h-3 w-3">
  <span class="**animate-ping** absolute inline-flex h-full w-full rounded-full bg-purple-400 opacity-75"></span>
  <span class="relative inline-flex rounded-full h-3 w-3 bg-purple-500"></span>
</span>
```

## Pulse

Add the `animate-pulse` utility to make an element gently fade in and out — useful for things like skeleton loaders.

```html lightBlue
<template preview>
  <div class="border border-light-blue-300 shadow rounded-md p-4 max-w-sm w-full mx-auto">
    <div class="flex space-x-4 animate-pulse">
      <div class="rounded-full bg-light-blue-400 h-12 w-12"></div>
      <div class="flex-1 space-y-4 py-1">
        <div class="h-4 bg-light-blue-400 rounded w-3/4"></div>
        <div class="space-y-2">
          <div class="h-4 bg-light-blue-400 rounded"></div>
          <div class="h-4 bg-light-blue-400 rounded w-5/6"></div>
        </div>
      </div>
    </div>
  </div>
</template>

<div class="border border-blue-300 shadow rounded-md p-4 max-w-sm w-full mx-auto">
  <div class="**animate-pulse** flex space-x-4">
    <div class="rounded-full bg-blue-400 h-12 w-12"></div>
    <div class="flex-1 space-y-4 py-1">
      <div class="h-4 bg-blue-400 rounded w-3/4"></div>
      <div class="space-y-2">
        <div class="h-4 bg-blue-400 rounded"></div>
        <div class="h-4 bg-blue-400 rounded w-5/6"></div>
      </div>
    </div>
  </div>
</div>
```

## Bounce

Add the `animate-bounce` utility to make an element bounce up and down — useful for things like "scroll down" indicators.

```html amber
<template preview>
  <div class="flex justify-center">
    <svg class="animate-bounce w-6 h-6 text-amber-900" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" stroke="currentColor">
      <path d="M19 14l-7 7m0 0l-7-7m7 7V3"></path>
    </svg>
  </div>
</template>

<svg class="**animate-bounce** w-6 h-6 ...">
  <!-- ... -->
</svg>
```

## Prefers-reduced-motion

You can conditionally apply animations and transitions using the `motion-safe` and `motion-reduce` variants:

```html
<button type="button" class="bg-indigo-600 ..." disabled>
  <svg class="**motion-safe:animate-spin** h-5 w-5 mr-3 ..." viewBox="0 0 24 24">
    <!-- ... -->
  </svg>
  Processing
</button>
```

**These variants are not enabled by default**, but you can enable them in the `variants` section of your `tailwind.config.js` file:

```js
// tailwind.config.js
module.exports = {
  // ...
  variants: {
    animation: ['responsive', 'motion-safe', 'motion-reduce']
  }
}
```

Learn more in the [state variants documentation](/docs/hover-focus-and-other-states#motion-safe).

## Responsive

To change or disable an animation at a specific breakpoint, add a `{screen}:` prefix to any existing animation utility. For example, use `md:animate-none` to apply the `animate-none` utility at only medium screen sizes and above.

```html
<div class="animate-spin **md:animate-none** ...">
  <!-- ... -->
</div>
```

For more information about Tailwind's responsive design features, check out the [Responsive Design](/docs/responsive-design) documentation.

## Customizing

Animations by their very nature tend to be highly project-specific. **The animations we include by default are best thought of as helpful examples**, and you're encouraged to customize your animations to better suit your needs.

By default, Tailwind provides utilities for four different example animations, as well as the `animate-none` utility. You change, add, or remove these by customizing the `animation` section of your theme configuration.

```diff-js
  // tailwind.config.js
  module.exports = {
    theme: {
      extend: {
        animation: {
+         'spin-slow': 'spin 3s linear infinite',
        }
      }
    }
  }
```

To add new animation `@keyframes`, use the `keyframes` section of your theme configuration:

```diff-js
  // tailwind.config.js
  module.exports = {
    theme: {
      extend: {
        keyframes: {
+         wiggle: {
+           '0%, 100%': { transform: 'rotate(-3deg)' },
+           '50%': { transform: 'rotate(3deg)' },
+         }
        }
      }
    }
  }
```

You can then reference these keyframes by name in the `animation` section of your theme configuration:

```diff-js
  // tailwind.config.js
  module.exports = {
    theme: {
      extend: {
        animation: {
+         wiggle: 'wiggle 1s ease-in-out infinite',
        }
      }
    }
  }
```

Learn more about customizing the default theme in the [theme customization documentation](/docs/theme#customizing-the-default-theme).

### Variants

<Variants plugin="animation" />

### Disabling

<Disabling plugin="animation" />
